package edu.geo.containers;

import java.util.List;

import org.codehaus.jackson.annotate.JsonWriteNullProperties;

import com.vividsolutions.jts.geom.Coordinate;
import com.vividsolutions.jts.geom.Geometry;
import com.vividsolutions.jts.geom.GeometryCollection;
import com.vividsolutions.jts.geom.GeometryFactory;
import com.vividsolutions.jts.geom.LinearRing;
import com.vividsolutions.jts.geom.Polygon;

import edu.geo.containers.geom.impl.Point;

@JsonWriteNullProperties(false)
public class GeoJson {
	private String type;
	/**
	 * El contenedor contiene objetos tipo string porque si se deja de objetos
	 * tipo Double, se genera un error al momento de leer valores en el json que
	 * no tengan cifras decimales como por ejemplo [ -90 -180 ].
	 */
	public List<?> coordinates;
	
	
	public List<GeoJson> geometries;

	/**
	 * @return the type
	 */
	public String getType() {
		return type;
	}

	/**
	 * @param type
	 *            the type to set
	 */
	public void setType(String type) {
		this.type = type;
	}

	public void setCoordinates(List<?> coordinates) {
		this.coordinates = coordinates;
	}

	public List<?> getCoordinates() {
		return coordinates;
	}
	
	public List<GeoJson> getGeometries() {
		return geometries;
	}

	public void setGeometries(List<GeoJson> geometries) {
		this.geometries = geometries;
	}

	@SuppressWarnings("unchecked")
	public Geometry toGeometry() {
		if (type.equals("Point")) {
			List<Number> values = (List<Number>) coordinates;
			Coordinate[] coord = new Coordinate[1];
			coord[0] = new Coordinate(((Number)values.get(0)).doubleValue(), ((Number)values
					.get(1)).doubleValue());
			Point g1 = edu.geo.containers.geom.impl.GeometryFactory.createPoint(coord);
			return g1;
		} else {

			if (type.equals("LineString")) {
				Geometry g1= null;
				List<List<Number>> values = (List<List<Number>>) (coordinates);
				List<Number> beginNode = values.get(0);
				List<Number> endNode = values.get(1);
					g1 = edu.geo.containers.geom.impl.GeometryFactory.createLineSegment(
						 edu.geo.containers.geom.impl.GeometryFactory.createPoint(beginNode.get(0).doubleValue(), beginNode.get(1).doubleValue()),
						 edu.geo.containers.geom.impl.GeometryFactory.createPoint(endNode.get(0).doubleValue(), endNode.get(1).doubleValue()));				
				return g1;
			} else if (type.equals("bbox")) {
				int i = 0;
				Coordinate[] coord = new Coordinate[coordinates.size()];
				List<List<Number>> values = (List<List<Number>>) (coordinates);
				for (List<Number> gPoint : values) {
							coord[i++] = new Coordinate(((Number) gPoint.get(0))
							.doubleValue(), ((Number) gPoint.get(1))
							.doubleValue());

				}
				return null;
			} else if (type.equals("Polygon")) {
				int i = 0;
				Polygon g1 ;
				
                List<List<Number>> listPoint = (List<List<Number>>) (coordinates.get(0));
                int size =listPoint.size();
                Coordinate[] coord= new Coordinate[size];
			    for (List<Number> gPoint : listPoint) {
							coord[i++] = new Coordinate(((Number) gPoint.get(0))
							.doubleValue(), ((Number) gPoint.get(1))
							.doubleValue());

				}

				LinearRing shell=(LinearRing)new GeometryFactory().createLinearRing(coord);
				g1 = new GeometryFactory().createPolygon(shell, null);
				return g1;
			}
			/**
			 * @author alejandro.sanchez
			 */
			else if (type.equals("GeometryCollection")) {
				if (!geometries.isEmpty())
				{
					Geometry[] aGeoms = new Geometry[geometries.size()];
					for (int i = 0; i < geometries.size(); ++i)
					{
						aGeoms[i] = (geometries.get(i).toGeometry());
					}
					GeometryCollection geomCollection = new GeometryFactory().createGeometryCollection(aGeoms);
					return geomCollection;
				}
			}
		}		
		return null;
	}
}
